const PENDING = 'pending' //等待状态
const FULFILLED = 'fulfilled'//成功状态
const REJECTED = 'rejected'//失败状态

class MyPromise {
    constructor(exector) {//执行器
        try {
            //创建peromise的时候传入的执行器会立刻执行
            exector(this.resolve, this.reject)//传递进来两个函数，一个是成功的函数，一个失败的函数
        } catch (err) {
            this.reject(err)
        }
    }
    status = PENDING;//设置默认的状态为等待状态
    value = undefined //设置一开始传递进来的成功的值为undefined
    reason = undefined //设置一开始传递进来的失败的值为undefined
    //fulfilledCallBack = undefined //把成功回调提升到全局
    //rejectedCallBack = undefined//把失败回调提升到全局
    fulfilledCallBack = [] //把成功回调修改为数组存储每一个成功的回调
    rejectedCallBack = []//把失败回调修改为数组存储每一个失败的回调
    resolve = (value) => { //value为传递进来的成功的值
        //用来改变状态，把状态变为成功
        if (this.status !== PENDING) return //因为状态是不可逆的，所以我们要在这里判断一下，以防更改状态 
        this.status = FULFILLED
        this.value = value // 把传递进来的成功的值赋值
        //this.fulfilledCallBack && this.fulfilledCallBack(this.value) //如果成功回调存在就执行成功回调并把成功的值传递给它
        while (this.fulfilledCallBack.length) this.fulfilledCallBack.shift()()
    }
    reject = (reason) => {//reason为传递进来的失败的原因
        //用来改变状态，把状态变为失败
        if (this.status !== PENDING) return //因为状态是不可逆的，所以我们要在这里判断一下，以防更改状态 
        this.status = REJECTED
        this.reason = reason// 把传递进来的失败的原因赋值
        //this.rejectedCallBack && this.rejectedCallBack(this.reason) //如果失败回调存在就执行失败回调并把失败的原因传递给它
        while (this.rejectedCallBack.length) this.rejectedCallBack.shift()()
    }

    then = (fulfilledCallBack, rejectedCallBack) => {//then方法中有两个回调函数一个成功的fulfilledCallBack，一个失败的rejectedCallBack
        fulfilledCallBack = fulfilledCallBack ? fulfilledCallBack : value => value //判断then方法中是否传递了成功函数，如果没有传递则默认把value向下传递
        rejectedCallBack = rejectedCallBack ? rejectedCallBack : reason => { throw reason }

        const promise = new MyPromise((resolve, reject) => {
            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        let x = fulfilledCallBack(this.value);
                        resolvePromise(promise, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                      let x = rejectedCallBack(this.reason);
                      resolvePromise(promise, x, resolve, reject)
                    }catch (e) {
                      reject(e);
                    }
                  }, 0)
            } else {
                //状态为等待状态，这是我们应该把成功的回调函数和失败的回调函数存储起来
                // this.fulfilledCallBack = fulfilledCallBack
                // this.rejectedCallBack = rejectedCallBack
                this.fulfilledCallBack.push(() => {
                    setTimeout(() => {
                        try {
                          let x = fulfilledCallBack(this.value);
                          resolvePromise(promise, x, resolve, reject)
                        }catch (e) {
                          reject(e);
                        }
                      }, 0)
                }) //将每一次成功的异步回调存储起来
                this.rejectedCallBack.push(() => {
                    setTimeout(() => {
                        try {
                          let x = rejectedCallBack(this.reason);
                          resolvePromise(promise, x, resolve, reject)
                        }catch (e) {
                          reject(e);
                        }
                      }, 0)
                })//将每一次失败的异步回调存储起来
            }
        })
        return promise
    }
    finally(callback) {
        return this.then(value => {
            return MyPromise.resolve(callback())
                .then(() => value)
        }, reason => {
            return MyPromise.resolve(callback())
                .then(() => { throw reason })
        })
    }
    catch = (rejectedCallBack) => {
        return this.then(undefined, rejectedCallBack)
    }
    static all = (array) => {
        let result = [] //存放最后 返回的值
        let index = 0;//用来记录array中的值是否执行完
        return new MyPromise((resolve, reject) => {
            function addData(key, value) {
                result[key] = value
                index++;
                if (index === array.length) {
                    //代表array执行完毕，直接返回result
                    resolve(result)
                }
            }
            for (let i = 0; i < array.length; i++) {
                if (array[i] instanceof MyPromise) {
                    //如果是promise对象
                    array[i].then(value => { addData(i, value) }, reason => { reject(reason) })
                } else {
                    //普通值
                    addData(i, array[i])
                }
            }
        })
    }
    static resolve = (value) => {
        if (value instanceof MyPromise) return value
        return new MyPromise((resolve, reject) => resolve(value))
    }
}

function resolvePromise(promise, x, resolve, reject) {
    if (promise === x) {
        return new Error("detelete promise")
    }
    if (x instanceof MyPromise) {
        //是promise
        x.then(value => { resolve(value) }, (reason) => { reject(reason) })
    } else {
        //普通值
        resolve(x)
    }
}

module.exports = MyPromise